<template>
  <div class="home">
    <div class="left">
      <video :srcObject.prop="leftVideo?.stream" autoplay></video>
    </div>
    <div class="right">
      <template v-for="(item, index) in videoList">
        <div
          v-if="leftVideo.display !== item.display"
          class="videoBox"
          :key="index"
          @click="changShowVideo(item)"
        >
          <video :srcObject.prop="item.stream" autoplay></video>
          <div v-if="item.data.videoState === 0" class="mask"></div>
          <div class="voiceTip">
            {{ item.data.audioState === 1 ? "麦克风已开启" : "麦克风已关闭" }}
            <button @click.stop="toggleState('audioState', item)">
              {{ item.data.audioState === 1 ? "关麦" : "开麦" }}
            </button>
          </div>
        </div>
      </template>
    </div>
    <div class="tool-bar">
      <button
        class="btn btn-primary"
        id="btn_start"
        @click="toggleState('audioState', masterVideo)"
      >
        {{ masterVideo?.data.audioState === 1 ? "关闭麦克风" : "打开麦克风" }}
      </button>
      <button
        class="btn btn-primary"
        id="btn_start"
        @click="toggleState('videoState', masterVideo)"
      >
        {{ masterVideo?.data.videoState === 1 ? "关闭摄像头" : "打开摄像头" }}
      </button>
      SRS:
      <input type="text" id="txt_host" class="input-medium" v-model="host" />
      Room:
      <input type="text" id="txt_room" class="input-small" v-model="room" />
      Display:
      <input
        type="text"
        id="txt_display"
        class="input-small"
        v-model="display"
      />
      <button class="btn btn-primary" id="btn_start" @click="startInit">
        加入房间
      </button>
      <button class="btn btn-primary" id="btn_start" @click="leave">
        离开房间
      </button>
    </div>
  </div>
</template>
<script>
import srsSig from "@/utils/srsSig.js";
import srsSdk from "@/utils/srsSdk.js";
import { display } from "./constance.js";
export default {
  name: "HomeView",
  data() {
    return {
      sig: null,
      publisher: null,
      players: {},
      host: "192.168.1.116",
      room: "12580",
      display: display,
      videoList: [], // 所有流视频（包括本地流即自己的流）
      curDisplay: "", // 用来展示左侧大屏的数据
    };
  },
  computed: {
    leftVideo() {
      if (!this.curDisplay) {
        return this.videoList.find((i) => i.display === this.display);
      } else {
        return this.videoList.find((i) => i.display === this.curDisplay);
      }
    },
    masterVideo() {
      return this.videoList.find((i) => i.display === this.display);
    },
  },
  methods: {
    //切换显示大屏
    changShowVideo(item) {
      this.curDisplay = item.display;
    },
    //离开房间
    leave() {
      if (this.sig) {
        this.sig.close();
        this.videoList = [];
        window.location.href = "/";
      }
    },
    async toggleState(type, item) {
      item.data[type] = item.data[type] ? 0 : 1;
      await this.sig.send({
        action: "control",
        room: this.room,
        display: item.display,
        data: JSON.stringify(item.data),
      });
    },
    async startInit() {
      // Connect to signaling first.
      if (this.sig) {
        this.sig.close();
      }

      this.sig = srsSig.SrsRtcSignalingAsync();
      this.sig.onmessage = (msg) => {
        console.log(msg);
        if (msg.event === "publish") {
          if (
            msg.peer &&
            msg.peer.publishing &&
            msg.peer.display !== this.display
          ) {
            this.startPlay(msg.peer.display);
          }
        }
        // 移除关闭的流
        if (msg.event === "join" || msg.event === "leave") {
          for (var k in this.players) {
            let stillAlive = false;
            msg.participants.forEach((participant) => {
              if (participant.display === k) stillAlive = true;
            });
            if (!stillAlive) {
              this.players[k].player.close();
              let index = this.videoList.findIndex((item) => item.display == k);
              this.videoList.splice(index, 1);
            }
          }
        }
        //关闭麦克风摄像头操作
        if (msg.event === "control") {
          this.videoList.forEach((item) => {
            if (item.display === msg.peer.display) {
              item.data = JSON.parse(msg.data);
            }
          });
        }
      };
      //链接
      const wsUrl = `ws://${this.host}/sig/v1/rtc?room=${this.room}&display=${this.display}`;
      await this.sig.connect(wsUrl);
      let r0 = await this.sig.send({
        action: "join",
        room: this.room,
        display: this.display,
      });
      // 如果信令正常，则开始发布媒体。
      const rtcUrl = `webrtc://${this.host}/${this.room}/${this.display}`;
      await this.startPublish(rtcUrl);
      await this.sig.send({
        action: "publish",
        room: this.room,
        display: this.display,
      });
      // 播放已经在房间里的流。
      r0.participants.forEach((participant) => {
        if (participant.display == this.display || !participant.publishing)
          return;
        this.startPlay(participant.display);
      });
    },
    //推送本地流
    startPublish(rtcUrl) {
      if (this.publisher) {
        this.publisher.close();
      }
      this.publisher = srsSdk.SrsRtcPublisherAsync();
      this.videoList.push({
        ...this.publisher,
        display: this.display,
        data: {
          audioState: 1,
          videoState: 1,
        },
      });
      return this.publisher
        .publish(rtcUrl)
        .then((res) => {
          console.log(res);
        })
        .catch((res) => {
          if (res.success) {
            console.log(res);
          } else {
            this.publisher.close();
            console.error(res);
          }
        });
    },
    startPlay(display) {
      // Remove exists.
      if (this.players[display]) {
        this.players[display].player.close();
      }
      // Clone a player from template.
      let player = srsSdk.SrsRtcPlayerAsync();
      this.players[display] = { player };
      let videos = {
        ...player,
        display: display,
        data: {
          audioState: 1,
          videoState: 1,
        },
      };
      let index = this.videoList.findIndex((item) => item.display == display);
      if (index < 0) {
        this.videoList.push(videos);
      }
      //Start play for this user.
      const rtcUrl = `webrtc://${this.host}/${this.room}/${display}`;
      player
        .play(rtcUrl)
        .then()
        .catch(function (reason) {
          player.close();
          console.error(reason);
        });
    },
  },
};
</script>
<style scoped lang="scss">
.home {
  display: flex;
  position: relative;
  height: 100vh;
  .left,
  .right {
    flex: 1;
    height: calc(100% - 100px);
    .videoBox {
      width: 180px;
      height: 135px;
      position: relative;
      display: flex;
      flex-direction: row;
      justify-content: center;
      align-items: center;
      background: #f5f5f5;
      padding: 5px 10;
      video {
        width: 180px;
        height: 135px;
      }
      .mask {
        position: absolute;
        top: 0;
        left: 0;
        width: 180px;
        height: 135px;
        background: rgba(0, 0, 0, 1);
        z-index: 99;
      }
      .voiceTip {
        position: absolute;
        bottom: 0;
        left: 0;
        width: 180px;
        height: 30px;
        background: rgba(0, 0, 0, 0.4);
        z-index: 100;
        font-size: 12px;
        line-height: 30px;
        color: #fff;
      }
    }
  }
  .tool-bar {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 100px;
    background-color: #999;
  }
}
</style>
